#!/bin/sh

#this script is brutal and verbose, has no tricks and is quite linear, then
#quite easy to deal with
#for the moment, it's hardcoded for a gcc toolchain... BAD! Since now
#gcc is a c++ piece of shit

#stolen from ffmpeg configure like a pig
set -e

#prevent locale nonsense from breaking basic text processing.
LC_ALL=C
export LC_ALL

toolkit_src_files='
toolkit/xqueue.c
toolkit/signal.c
toolkit/keyboard.c
toolkit/prop.c
toolkit/display.c
toolkit/paths.c
toolkit/xml.c
'

wm_src_files='
wm/actions.c 
wm/client.c 
wm/config.c 
wm/debug.c 
wm/event.c 
wm/focus.c 
wm/focus_cycle.c 
wm/focus_cycle_indicator.c 
wm/frame.c 
wm/grab.c 
wm/group.c 
wm/keyboard.c 
wm/keytree.c 
wm/mouse.c 
wm/moveresize.c 
wm/wm.c 
wm/place.c 
wm/resist.c 
wm/screen.c 
wm/stacking.c 
wm/translate.c 
wm/window.c
'

wm_action_src_files='
wm/actions/all.c 
wm/actions/addremovedesktop.c 
wm/actions/breakchroot.c 
wm/actions/close.c 
wm/actions/cyclewindows.c 
wm/actions/debug.c 
wm/actions/desktop.c 
wm/actions/directionalwindows.c 
wm/actions/execute.c 
wm/actions/exit.c 
wm/actions/focus.c 
wm/actions/focustobottom.c 
wm/actions/fullscreen.c 
wm/actions/growtoedge.c 
wm/actions/if.c 
wm/actions/kill.c 
wm/actions/layer.c 
wm/actions/lower.c 
wm/actions/maximize.c 
wm/actions/move.c 
wm/actions/moverelative.c 
wm/actions/moveresizeto.c 
wm/actions/movetoedge.c 
wm/actions/omnipresent.c 
wm/actions/raise.c 
wm/actions/raiselower.c 
wm/actions/resize.c 
wm/actions/resizerelative.c 
wm/actions/restart.c 
wm/actions/showdesktop.c 
wm/actions/unfocus.c
'

clean_do()
{
    rm -Rf fake_root
    all_src_files="
        $toolkit_src_files
        $wm_action_src_files
        $wm_src_files
    "
    for all_src_file in $all_src_files
    do
      all_pp_file=${all_src_file%.c}
      all_pp_file=${all_pp_file}.pp.c
      rm -f "$all_pp_file"
      all_o_file=${all_src_file%.c}
      all_o_file=${all_o_file}.o
      rm -f ${all_o_file}
      #clean directories, but keep root of build tree
      tgt_dir=$(dirname $all_src_file)
      if test -d $tgt_dir -a "$tgt_dir" != "."; then
        rmdir --ignore-fail-on-non-empty -p $tgt_dir
      fi
    done
    exit 0
}

sep_start()
{
  printf '###############################################################################\n'
}

sep_end()
{
  printf '###############################################################################\n\n'
}

################################################################################

is_in(){
    value=$1
    shift
    for var in $*; do
        [ $var = $value ] && return 0
    done
    return 1
}

die_unknown(){
    echo "Unknown option \"$1\"."
    echo "See $0 --help for available options."
    exit 1
}

set_default(){
    for opt; do
        eval : \${$opt:=\$${opt}_default}
    done
}

CMDLINE_SET='
    bin_dir
    config_dir
    data_dir
    locale_dir
    lboxwm_cpp
    lboxwm_cc
    lboxwm_ccld
    pkg_config
'
#command line set defaults
bin_dir_default=/bin
config_dir_default=/etc
data_dir_default=/share
locale_dir_default=$data_dir_default/locale

#-------------------------------------------------------------------------------
#This defaults are for gcc, tested with version 4.7.3.
lboxwm_cpp_default='gcc -E -Wall -Wextra'
lboxwm_cc_default="gcc -c -Wall -Wextra -O0"
lboxwm_ccld_default='gcc -Wl,-O10,-s'
#-------------------------------------------------------------------------------
pkg_config_default=pkg-config

set_default $CMDLINE_SET

show_help(){
    cat <<EOF
Usage: make [options] [operations]

Operations: [default is to build the lboxwm binary]:
  clean                                clean build products

Options: [defaults in brackets after descriptions]

Help options:
  --help                               print this message

Standard options:
  --enable-nls                         enable internationalized messages [no]
  --bin-dir=DIR                        lboxwm binary directory [$bin_dir_default]
  --config-dir=DIR                     the configuration directory [$config_dir_default]
  --data-dir=DIR                       the architecture independant root dir [$data_dir_default]
  --locale-dir=DIR                     the locale directory[$locale_dir_default]

Advanced options:
  --pkg-config=PKG_CONFIG              use PKG_CONFIG pkg-config command for target libraries [$pkg_config_default]
  --lboxwm-cpp=CPP                     use CPP compiler command line CPP for target lboxwm process [$lboxwm_cpp_default]
  --lboxwm-cc=CC                       use C compiler command line CC for target lboxwm process objects [$lboxwm_cc_default]
  --lbox-ccld=CCLD                     use linker command line CCLD for target lboxwm process [$lboxwm_ccld_default]
EOF
  exit 0
}

################################################################################

for opt do
    optval="${opt#*=}"
    case "$opt" in
        clean) clean_do
        ;;
        --help|-h) show_help
        ;;
        --enable-nls)
            CPPFLAGS="$CPPFLAGS -DENABLE_NLS"
            enable_nls=1
        ;;
        *)
            optname=${opt%%=*}
            optname=${optname#--}
            optname=$(echo "$optname" | sed 's/-/_/g')
            if is_in $optname $CMDLINE_SET; then
                eval $optname='$optval'
            else
                die_unknown $opt
            fi
        ;;
    esac
done

################################################################################

sep_start;echo 'looking for source path:'
if test -f make; then
    src_path=.
else
    src_path=$(cd $(dirname "$0"); pwd)
    echo "$src_path" | grep -q '[[:blank:]]' &&
        die "out of tree builds are impossible with whitespace in source path."
    test -e "$src_path/config.h" &&
        die "out of tree builds are impossible with config.h in source dir."
fi
echo "source path is $src_path";sep_end

################################################################################

#deal with the nls... maybe useless for minimal window manager
if test -n "$enable_nls"; then
    sep_start;echo 'generating internationalized message files:'
    for po in $(find $src_path/po -name '*.po')
    do
        langs="$langs $(basename $po .po)"
    done

    for lang in $langs
    do
        echo "LANG=$lang"
        mkdir -p fake_root/$locale_dir/$lang/LC_MESSAGES
        msgfmt $src_path/po/$lang.po -o fake_root/$locale_dir/$lang/LC_MESSAGES/lboxwm.mo
    done
    sep_end
fi

################################################################################

#define variable in source
CPPFLAGS="$CPPFLAGS -DCONFIGDIR=\"$config_dir\""
CPPFLAGS="$CPPFLAGS -DDATADIR=\"$data_dir\""
CPPFLAGS="$CPPFLAGS -DLOCALEDIR=\"$locale_dir\""
CPPFLAGS="$CPPFLAGS -DPACKAGE_VERSION=\"1.0\""
CPPFLAGS="$CPPFLAGS -DPACKAGE_BUGREPORT=\"sylvain.bertrand@gmail.com\""

################################################################################

all_src_files="
   $toolkit_src_files
   $wm_action_src_files
   $wm_src_files
"


################################################################################

sep_start;echo 'C preprocess lboxwm src files:'
for all_src_file in $all_src_files
do
    all_pp_c_file=${all_src_file%.c}
    all_pp_c_file=${all_pp_c_file}.pp.c
    echo "LBOXWM_CPP $all_src_file->$all_pp_c_file"
    mkdir -p $(dirname $all_pp_c_file)
    $lboxwm_cpp $CPPFLAGS -I. -I$src_path -o $all_pp_c_file \
        $($pkg_config --cflags-only-I xproto \
                                      glib-2.0 \
                                      x11 \
                                      xext \
                                      xinerama \
                                      xrandr \
                                      xcursor \
                                      libxml-2.0) \
        $src_path/$all_src_file
    all_pp_c_files="$all_pp_c_file $all_pp_c_files"
done
sep_end

################################################################################

sep_start;echo 'compile lboxwm preprocessed src files:'
for all_pp_c_file in $all_pp_c_files
do
    all_obj_file=${all_pp_c_file%.pp.c}
    all_obj_file=${all_obj_file}.o
    echo "LBOXWM_CC $all_pp_c_file-->$all_obj_file"
    $lboxwm_cc -o $all_obj_file \
        $($pkg_config --cflags-only-other xproto \
                                          glib-2.0 \
                                          x11 \
                                          xext \
                                          xinerama \
                                          xrandr \
                                          xcursor \
                                          libxml-2.0) \
        $all_pp_c_file
    all_obj_files="$all_obj_file $all_obj_files"
done
sep_end

################################################################################

sep_start;echo 'link the lboxwm objects to produce the lboxwm binary:'
mkdir -p fake_root/$bin_dir
echo "LBOXWM_CCLD lboxwm"
$lboxwm_ccld -o fake_root/$bin_dir/lboxwm \
    $($pkg_config --libs xproto \
                       glib-2.0 \
                       x11 \
                       xext \
                       xinerama \
                       xrandr \
                       xcursor \
                       libxml-2.0) \
    $all_obj_files
sep_end

################################################################################

sep_start;echo 'install configuration files in fake root:'
mkdir -p fake_root/$config_dir/xdg/lboxwm
cp -f $src_path/data/rc.xml fake_root/$config_dir/xdg/lboxwm
cp -f $src_path/data/rc.xsd fake_root/$config_dir/xdg/lboxwm
sep_end
